﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Reflection.Metadata;
using System.Security.Claims;
using System.Text;
using System.Text.RegularExpressions;
using 第二课堂评审系统.Models;

namespace 第二课堂评审系统.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]//表示需要token标识才能访问
    public class PublicController : ControllerBase
    {
        private readonly IOptionsSnapshot<JWTSettings> jwtSettingsOpt;
        private readonly _MyDbContext Db;
        public PublicController(IOptionsSnapshot<JWTSettings> jwtSettingsOpt, _MyDbContext db)
        {
            this.jwtSettingsOpt = jwtSettingsOpt;
            Db = db;
        }
        public record LogUser(string username,string password);
     

        [AllowAnonymous]
        [HttpPost]//登录
        public ActionResult<string> login([FromBody] LogUser user)
        {
            
            User loginUser = Db.Users.Where(u => u.StuNum.ToString() == user.username && u.passWord == MD5Algorithm.ChangeToMD5(user.password))!.Include(u => u.Roles).ToList().SingleOrDefault()!;
            if (loginUser != null)
            {
                if(loginUser.isDeleted==true)
                {
                    return BadRequest("用户不存在");
                }
                //登录成功生成token
                List<Claim> claims = new();
                claims.Add(new Claim(ClaimTypes.NameIdentifier, loginUser!.StuNum.ToString()));//token中添加用户ID信息
                foreach (Role i in loginUser.Roles!)//token中添加用户身份
                {
                    claims.Add(new Claim(ClaimTypes.Role, i.Name));
                }
                //JWT的传输中不建议设置太多东西，不然耗费流量

                //接下来正式生成token
                string key = jwtSettingsOpt.Value.SecKey;//通过依赖注入获取密钥
                DateTime expire = DateTime.Now.AddSeconds(jwtSettingsOpt.Value.ExpireSecond);//获取过期时间
                byte[] secBytes = Encoding.UTF8.GetBytes(key);//密钥转二进制
                var secKey = new SymmetricSecurityKey(secBytes);
                var credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);
                var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expire, signingCredentials: credentials);
                string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
                return jwt;
            }
            else
            {
                return BadRequest("用户不存在");
            }
        }
        [HttpPost]//修改个人信息
        public ActionResult changeInfo(IFormFile? file, string? newSphone, string? newScollege, string? newSaddress, string? newScalladdress)
        {
            //获取token中的值
            var UID = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
            User user = Db.Users.Where(u => u.StuNum.ToString() == UID).ToList().SingleOrDefault()!;
            if (file != null && file.Length != 0)
            {
                //判断并删除旧文件
                if (user.avatar != null)
                {

                    var pt = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot\\Avatar", user.avatar!);
                    if (System.IO.File.Exists(pt))
                    {
                        System.IO.File.Delete(pt);
                    }
                }
                //上传头像
                var path = string.Format("{0}_{1}", DateTime.Now.Ticks, file.FileName);
                var path1 = Path.Combine("wwwroot\\Avatar", path);
                var path2 = Path.Combine(Directory.GetCurrentDirectory(), path1);

                using (var stream = new FileStream(path2, FileMode.Create))
                {
                    file.CopyTo(stream);
                }
                user.avatar = path;
                if (newSphone != null)
                    user.telPhone = newSphone;
                if (newScollege != null)
                    user.college = newScollege;
                if (newSaddress != null)
                    user.address = newSaddress;
                if (newScalladdress != null)
                    user.contactAddress = newScalladdress;
                Db.SaveChanges();
                return Ok("个人信息修改成功");
            }
            else
            {
                if (newSphone != null)
                    user.telPhone = newSphone;
                if (newScollege != null)
                    user.college = newScollege;
                if (newSaddress != null)
                    user.address = newSaddress;
                if (newScalladdress != null)
                    user.contactAddress = newScalladdress;
                Db.SaveChanges();
                return Ok("个人信息修改成功");
            }


        }
        [HttpGet]//获取用户个人信息
        public ActionResult getMyInfo()
        {
            //获取token中的值
            var UID = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
            User user = Db.Users.Where(u => u.StuNum.ToString() == UID).Include(u => u.Roles).ToList().SingleOrDefault()!;
            var js = new
            {
                avatarUrl = user.avatar,
                Sname = user.Name,
                Sphone = user.telPhone,
                Saddress = user.address,
                Scollege = user.college,
                Scalladdress = user.contactAddress,
                Sidentity = user.Roles![0].Name
            };

            return new JsonResult(js);
        }
        [HttpGet]//获取用户角色信息
        public ActionResult getUserInfo()
        {
            var UID = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
            User user = Db.Users.Where(u => u.StuNum.ToString() == UID).Include(u => u.Roles).ToList().SingleOrDefault()!;
            var js = new
            {
                id = UID.ToString(),
                info = new
                {
                    nickName = user.Name,
                    avatarUrl ="/Avatar/"+ user.avatar,
                    role = user.Roles[0].Name
                }

            };
            return new JsonResult(js);
        }
        public record passInfo(string sourcePassword,string newPassword);
        [HttpPut]//修改密码
        public ActionResult changePassword([FromBody]passInfo passinfo)
        {
            if(passinfo.newPassword==null)
            {
                return BadRequest("密码不能为空");
            }
            //密码的要求:1.特殊符号'-!"#$%&()*,./:;?@[]^_`{|}~+<=> 2.数字 3.英文字母 4.最小长度6
            string pattern = @"^(?=.*[a-zA-Z])(?=.*\d)(?=.*[-!""#$%&'()*+,./:;<=>?@[\\\]^_`{|}~])[a-zA-Z\d-!""#$%&'()*+,./:;<=>?@[\\\]^_`{|}~]{6,}$";
            if (Regex.IsMatch(passinfo.newPassword, pattern))
            {
                var UID = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
                User user = Db.Users.Where(u => u.StuNum.ToString() == UID).ToList().SingleOrDefault()!;
                if (user.passWord == passinfo.sourcePassword)
                {
                    user.passWord = passinfo.newPassword;
                    Db.SaveChanges();
                    return Ok("密码修改成功");
                }
                else return BadRequest("密码不正确");
            }
            else return BadRequest("新密码未达要求");
        }

        #region 获得阶段时间
        [HttpGet]
        public ActionResult getAllTime()
        {
            using _MyDbContext Context = new _MyDbContext();
            ControllActionTime c1 = Context.ControllActionTimes.Where(c => c.Name == "审核时间").FirstOrDefault()!;
            ControllActionTime c2 = Context.ControllActionTimes.Where(c => c.Name == "初赛时间").FirstOrDefault()!;
            ControllActionTime c3 = Context.ControllActionTimes.Where(c => c.Name == "决赛时间").FirstOrDefault()!;

            var FirstStage = c1 != null ? new { startTime = c1.BeginTime.ToString("yyyy-MM-dd HH:mm:ss"), endTime = c1.EndTime.ToString("yyyy-MM-dd HH:mm:ss") } :
                                        new { startTime = DateTime.Now.AddYears(3000).ToString("yyyy-MM-dd HH:mm:ss"), endTime = DateTime.Now.AddYears(3001).ToString("yyyy-MM-dd HH:mm:ss") };
            var SecondStage = c2 != null? new { startTime = c2.BeginTime.ToString("yyyy-MM-dd HH:mm:ss"), endTime = c2.EndTime.ToString("yyyy-MM-dd HH:mm:ss") }:
                                          new { startTime = DateTime.Now.AddYears(3000).ToString("yyyy-MM-dd HH:mm:ss"), endTime = DateTime.Now.AddYears(3001).ToString("yyyy-MM-dd HH:mm:ss") };
            var ThirdStage = c3!=null? new { startTime = c3.BeginTime.ToString("yyyy-MM-dd HH:mm:ss"), endTime = c3.EndTime.ToString("yyyy-MM-dd HH:mm:ss") }:
                                        new { startTime = DateTime.Now.AddYears(3000).ToString("yyyy-MM-dd HH:mm:ss"), endTime = DateTime.Now.AddYears(3001).ToString("yyyy-MM-dd HH:mm:ss") };
            var js = new { FirstStage,  SecondStage, ThirdStage };
            return new JsonResult(js);
        }
        #endregion

        [HttpGet]
        public IActionResult getRank()
        {
            //获取token中的值
            var UID = this.User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
            User user = Db.Users.Include(u=>u.partnar).ThenInclude(u=>u.project).Where(u => u.StuNum.ToString() == UID).ToList().SingleOrDefault()!;
           
            var js = new
            {
                itemName= user.partnar.project.Name,
                itemRank= user.partnar.project.Rank
              };
            return new JsonResult(js);

        }
    }
}
